package main

import "fmt"

//１.定义Animal结构体
type Animal struct {
	name string
	age  int
}

//2.定义Animal的方法
func (a Animal) eat() {
	fmt.Println(a.name, "在吃东西　．．．")
}

func (a Animal) printInfo() {
	fmt.Printf("名字：%s,年龄：%d\n", a.name, a.age)
}
//定义一个Cat和Dog两个结构体，并继承Animal结构体
type Cat struct {
	Animal //把Animal继承到Cat结构体中，这样cat结构体就能使用Animal中的参数和方法
	color string //也可以自己定义自己的属性和方法　
}

func (c Cat) eat()  {
	//继承了Animal所有属性和方法后，马上就可以调用Animal中的任何属性
	fmt.Printf("%s小猫：%s,在吃鱼\n",c.color,c.name)
}

type Dog2 struct {
	Animal
	sex string
}

func (d Dog2) lookDoor()  {
	//继承了Animal所有属性和方法后，马上就可以调用Animal中的任何属性
	fmt.Printf("%s小狗:%s，在看家\n",d.sex,d.name)
}


func main() {
	a1 := Animal{"兔子", 3}
	a1.eat() //兔子 在吃东西　．．．
	a1.printInfo() //名字：兔子,年龄：3

	c1:=Cat{Animal{"tom",3},"白色"}
	c1.eat() //白色小猫：tom,在吃鱼 把父类方法eat重写了
	c1.printInfo() //名字：tom,年龄：3
	/*虽然printInfo的方法接收者是Animal，为什么c1也可以调用呢．因为
	Cat结构体继承了Animal的所有属性和方法．所以可以随便调用Animal的任何
	属性和方法．不受限制．这就是继承的好处
	*/

	d1:=Dog2{Animal{"旺旺",5},"公狗"}
	d1.lookDoor() //公狗小狗:旺旺，在看家
	d1.eat() //旺旺 在吃东西　．．． 子类对象直接能访问父类的所有方法
	d1.printInfo() //名字：旺旺,年龄：5
	//和上面程序一样，既然　
}

